import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import au.com.bytecode.opencsv.CSVReader;

import java.awt.*;
import java.applet.*;
import java.util.Random;

public class calcFee extends Applet {
	
	
	
	// example of communication between javascript and Applet
	private String hi = "Before";
	
	public void changeStr(){
		this.hi = "Hi!!!";
	}
	public String Hello(){
		//System.out.println("Hello, World!");
		//Graphics g = getGraphics();
		//g.drawString("Hello from JAVA!", 10, 10);
		return "<br>" + this.hi + "</br>";
	}
	//////////////////////////////////////////////////////////

	private static int N = 0;
	private static lotInfo[] Lots;

	public static int findID(int id)
	{
		for (int i=0; i<N; i++){
			if (Lots[i].getID()==id) return i;
		}
		return -1;
	}
	
	public void loadData() {
		String[][] data1 = {
			{"1","Fluno Center (Lot 83)","601 University Ave, Madison, WI 53715, USA","10","10","99999"},
			{"2","State Street Campus","415 N Lake St, Madison, WI 53715, USA","99999","5","205"},
			{"3","Southeast Campus/46 Ramp","334 N Lake St, Madison, WI 53715, USA","99999","99999","99999"},
			{"4","Buckeye P2 - 200 West Gilman Street","200 W Gilman St, Madison, WI 53703, USA","99999","99999","99999"},
			{"5","Buckeye P1 - 200 West Gorham Street","200 W Gorham St, Madison, WI 53703, USA","99999","99999","99999"},
			{"6","Downtown Parking Close To Campus, Avail. Mid-May!","126 Langdon St, Madison, WI 53703, USA","99999","99999","125"},
			{"7","Underground Heated Parking Available Now","501 N Henry St, Madison, WI 53703, USA","99999","99999","150"},
			{"8","Memorial Union/Lot 1","790 Langdon St, Madison, WI 53706, USA","99999","99999","99999"},
			{"9","Underground Parking In The Heart Of Madison","619 W Mifflin St, Madison, WI 53703, USA","99999","99999","121"},
			{"10","Parking Near The Kohl Center","114 N Bedford St, Madison, WI 53703, USA","99999","99999","63"},
			{"11","Overture Center","300 W Mifflin St, Madison, WI 53703, USA","99999","5","124"},
			{"12","Summer Parking-/Langdon Street","120 Langdon St, Madison, WI 53703, USA","99999","99999","300"},
			{"13","South of Art Lofts/Lot 91","115 N Frances St, Madison, WI 53703, USA","99999","99999","99999"},
			{"14","Helen C White/Lot 6","600 N Park St, Madison, WI 53706, USA","99999","99999","99999"},
			{"16","State Street Capitol","200 N Carroll St, Madison, WI 53703, USA","99999","5","163"},
			{"17","Grainger Hall","975 University Ave, Madison, WI 53715, USA","99999","99999","99999"},
			{"18","Madison Concourse Hotel","1 W Dayton St, Madison, WI 53703, USA","10","10","99999"},
			{"19","Underground Parking Downtown Madison (Four Seasons At Park And Spring)","903 Spring St, Madison, WI 53715, USA","99999","99999","100"},
			{"20","Summer Parking: Covered Reserved Secure Spot","503 W Doty St, Madison, WI 53703, USA","99999","99999","90"},
			{"21","Dane County","113 S Henry St, Madison, WI 53703, USA","99999","99999","135"},
			{"24","Parking Space For Rent","532 W Wilson St, Madison, WI 53703, USA","99999","99999","65"},
			{"26","Lot 51","30 N Mills St, Madison, WI 53715, USA","99999","99999","99999"},
			//{"27","Zoology Research/Lot 56","255 N Charter St, University of Wisconsin-Madison, Madison, WI 53706, USA","99999","99999","99999"},
			{"28","Capitol Square North Garage","100 N Webster St, Madison, WI 53703, USA","99999","5","139"},
			{"29","Weeks Hall/Lot 54","University Wisconsin System, 117 N Charter St, Madison, WI 53715, USA","99999","99999","99999"},
			{"30","Elizabeth Waters/Lot 25","1190 Observatory Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"33","88 P2","10 E Doty St, Madison, WI 53703, USA","99999","99999","99999"},
			{"34","John Nolen Drive","1 John Nolen Dr, Madison, WI 53703, USA","12","4","99999"},
			{"35","Observatory Hill/Lot 26","1411 Observatory Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"37","Union South - W Dayton St","1307 W Dayton St, Madison, WI 53715, USA","10","10","99999"},
			{"38","McArdle Lab/MSC/Lot 20","1390 University Ave, Madison, WI 53706, USA","99999","99999","99999"},
			{"39","Government East Garage","200 S Pinckney St, Madison, WI 53703, USA","99999","5","210"},
			{"40","88 P1","10 E Wilson St, Madison, WI 53703, USA","99999","99999","99999"},
			{"41","Brayton P2","10 S Butler St, Madison, WI 53703, USA","99999","99999","99999"},
			{"43","Campus Underground Parking Spot","1401 Monroe St, Madison, WI 53711, USA","99999","99999","100"},
			{"44","Tripp Hall /Lot 34 - 1480 Tripp","1480 Tripp Cir, Madison, WI 53706, USA","99999","99999","99999"},
			{"45","Wilson","400 S Hancock St, Madison, WI 53703, USA","99999","99999","121"},
			{"46","North of Camp Randall/Lot 17","1525 Engineering Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"47","Crew Boathouse /Lot 35","655 Babcock Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"48","Babcock Hall/Stock Pavilion/Lot 40","1655 Linden Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"49","Blair","410 S Blair St, Madison, WI 53703, USA","99999","99999","114"},
			{"50","Russell Labs/Lot 36","1645 Observatory Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"51","Holt Commons/Lot 32","Kronshage Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"52","West of Field House /Lot 19","10 N Breese Terrace, Madison, WI 53706, USA","99999","99999","99999"},
			{"53","Foundation/Enzyme Institute/Lot 41","1820 University Ave, Madison, WI 53726, USA","99999","99999","99999"},
			{"54","Saint Mary's Hospital","N Brooks St, Madison, WI 53715, USA","5","5","99999"},
			{"55","Dairy Research/Meat Lab/Lot 39","1811 Linden Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"56","Bradley/Sullivan Dorms/Lot 37","651 Elm Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"57","Wingra","1700 Monroe St, Madison, WI 53711, USA","99999","99999","99999"},
			{"58","Lot 58","630 Elm Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"59","Agronomy/Seed Labs/Lot 43","1035 Observatory Dr, Madison, WI 53706, USA","99999","99999","99999"},
			{"60","Jenny Street Garage For Rent","952 Jenifer St, Madison, WI 53703, USA","99999","99999","50"},
		};
		int dataN1 = 51;
		String[][] data2 = {
			{"2","MTWTF","0","24","1.25"},
			{"3","MTWTF","0","24","2.0"},
			{"3","SatSun","0","24","2.0"},
			{"3","MTWTFSatSun","0","24","2.0"},
			{"4","MTWTFSatSun","0","24","1.45"},
			{"5","MTWTFSatSun","0","24","1.45"},
			{"8","MTWTFSat","22","24","0.0"},
			{"8","MTWTFSat","0","7","0.0"},
			{"8","Sun","0","24","0.0"},
			{"8","MTWTFSat","7","22","1.25"},
			{"11","MTWTF","0","24","0.7"},
			{"13","MTWTF","17","24","0.0"},
			{"13","MTWTF","0","7","0.0"},
			{"13","SatSun","0","24","0.0"},
			{"13","MTWTF","7","17","1.25"},
			{"14","MTWTFSat","20","24","0.0"},
			{"14","MTWTFSat","0","7","0.0"},
			{"14","Sun","0","24","0.0"},
			{"14","MTWTFSat","7","20","1.25"},
			{"16","MTWTF","0","24","1.0"},
			{"17","MTWTFSat","20","24","0.0"},
			{"17","MTWTFSat","0","7","0.0"},
			{"17","Sun","0","24","0.0"},
			{"17","MTWTFSat","7","20","1.25"},
			{"21","MTWTFSatSun","0","24","1.5"},
			{"26","MTWTF","17","24","0.0"},
			{"26","MTWTF","0","7","0.0"},
			{"26","SatSun","0","24","0.0"},
			{"26","MTWTF","7","17","1.25"},
			//{"27","MTWTF","17","24","0.0"},
			//{"27","MTWTF","0","7","0.0"},
			//{"27","SatSun","0","24","0.0"},
			//{"27","MTWTF","7","17","1.25"},
			{"28","MTWTF","0","24","0.8"},
			{"29","MTWTF","17","24","0.0"},
			{"29","MTWTF","0","7","0.0"},
			{"29","SatSun","0","24","0.0"},
			{"29","MTWTF","7","17","1.25"},
			{"30","MTWTF","17","24","0.0"},
			{"30","MTWTF","0","7","0.0"},
			{"30","SatSun","0","24","0.0"},
			{"30","MTWTF","7","17","1.25"},
			{"33","MTWTFSatSun","0","24","1.25"},
			{"34","MTWTF","0","24","1.4"},
			{"35","MTWTF","17","24","0.0"},
			{"35","MTWTF","0","7","0.0"},
			{"35","SatSun","0","24","0.0"},
			{"35","MTWTF","7","17","1.25"},
			{"38","MTWTF","17","24","0.0"},
			{"38","MTWTF","0","7","0.0"},
			{"38","SatSun","0","24","0.0"},
			{"38","MTWTF","7","17","1.25"},
			{"39","MTWTF","0","24","1.4"},
			{"40","MTWTFSatSun","0","24","1.25"},
			{"41","MTWTFSatSun","0","24","1.2"},
			{"44","MTWTF","17","24","0.0"},
			{"44","MTWTF","0","7","0.0"},
			{"44","SatSun","0","24","0.0"},
			{"44","MTWTF","7","17","1.25"},
			{"46","MTWTF","17","24","0.0"},
			{"46","MTWTF","0","7","0.0"},
			{"46","SatSun","0","24","0.0"},
			{"46","MTWTF","7","17","1.25"},
			{"47","MTWTF","17","24","0.0"},
			{"47","MTWTF","0","7","0.0"},
			{"47","SatSun","0","24","0.0"},
			{"47","MTWTF","7","17","1.25"},
			{"48","MTWTF","17","24","0.0"},
			{"48","MTWTF","0","7","0.0"},
			{"48","SatSun","0","24","0.0"},
			{"48","MTWTF","7","17","1.25"},
			{"49","MTWTF","18","24","0.75"},
			{"49","MTWTF","0","6","0.75"},
			{"50","MTWTF","17","24","0.0"},
			{"50","MTWTF","0","7","0.0"},
			{"50","SatSun","0","24","0.0"},
			{"50","MTWTF","7","17","1.25"},
			{"51","MTWTF","17","24","0.0"},
			{"51","MTWTF","0","7","0.0"},
			{"51","SatSun","0","24","0.0"},
			{"51","MTWTF","7","17","1.25"},
			{"52","MTWTF","17","24","0.0"},
			{"52","MTWTF","0","7","0.0"},
			{"52","SatSun","0","24","0.0"},
			{"52","MTWTF","7","17","1.25"},
			{"53","MTWTF","17","24","0.0"},
			{"53","MTWTF","0","7","0.0"},
			{"53","SatSun","0","24","0.0"},
			{"53","MTWTF","7","17","1.25"},
			{"54","MTWTFSatSun","0","24","1.0"},
			{"55","MTWTF","17","24","0.0"},
			{"55","MTWTF","0","7","0.0"},
			{"55","SatSun","0","24","0.0"},
			{"55","MTWTF","7","17","1.25"},
			{"56","MTWTF","17","24","0.0"},
			{"56","MTWTF","0","7","0.0"},
			{"56","SatSun","0","24","0.0"},
			{"56","MTWTF","7","17","1.25"},
			{"57","MTWTFSatSun","0","24","0.75"},
			{"58","MTWTF","17","24","0.0"},
			{"58","MTWTF","0","7","0.0"},
			{"58","SatSun","0","24","0.0"},
			{"58","MTWTF","7","17","1.25"},
			{"59","MTWTFSat","22","24","0.0"},
			{"59","MTWTFSat","0","7","0.0"},
			{"59","Sun","0","24","0.0"},
			{"59","MTWTFSat","7","22","1.25"},
		};
		int dataN2 = 101;
		
		this.N = dataN1;
		Lots = new lotInfo[N];
		for (int i=0;i<dataN1;i++)
		{
			Lots[i] = new lotInfo();
			Lots[i].initialize(Integer.parseInt(data1[i][0]),data1[i][1],data1[i][2],Integer.parseInt(data1[i][3]),Integer.parseInt(data1[i][4]),Integer.parseInt(data1[i][5]));
		}

		for (int i=0;i<dataN2;i++)
		{
			int j = findID(Integer.parseInt(data2[i][0]));
			Lots[j].addRule(data2[i][1],Integer.parseInt(data2[i][2]),Integer.parseInt(data2[i][3]),Double.parseDouble(data2[i][4]));
		}
	}
	
	public int getN(){
		return N;
	}
	
	public String getAddr(int k){
		if (k==-1) return "975 University Avenue, Madison WI";
		return Lots[k].getAddr();
	}
	
	boolean[] nearD = new boolean[62];
	double[][] distance = new double[62][62];
	
	private int findStID(String st) {
		for (int i=0; i<N; i++){
			//System.out.println(Lots[i].getAddr());
			if (st.contains(Lots[i].getAddr())) return i;
		}
		if (st.contains("STA")) return 0;
		if (st.contains("DES")) return 61;		
		return -1;
	}
	
	public void setNearD(String st) {
		
		this.nearD[findStID(st)] = true;
		//this.nearD[Lots[i].getID()] = true;
	}
	/*public void setDist(int i, int j, double v){
		this.distance[i][j] = v;
	}*/
	public void setDist(String from, String to, int v){
		int i,j;
		i = findStID(from);
		j = findStID(to);

		this.distance[i][j] = (double)v;
	}
	public void initialDist(){
		for (int i=0;i<62;i++)
			this.nearD[i] = false;
		this.nearD[0] = true;
		this.nearD[61] = true;
		for (int i=0;i<62;i++)
			for (int j=0;j<62;j++)
				this.distance[i][j] = 99999;
	}
	public static ArrayList<Double> getParkFee(int day, int start, int end, ArrayList<Integer> candids){
		ArrayList<Double> fees =new ArrayList();
		for(int i=0;i<candids.size();i++){
			fees.add(Lots[candids.get(i)].getFee(day, start, end));	
		}
		
		return fees;
	}
	
	int optN = 0;
	double[][] optMtx;
	int[] match;
	
	public String getOptimal()
	{
		/////////////////////////////////////
		int i,j,k;
		int n;
		match = new int[62];
		
		nearD[61]=false;
		n=0;
		for (i=0;i<62;i++){
			if (!this.nearD[i]) continue;
			match[n] = i;
			n++;
		}
		
		this.optN = n;
		
		this.optMtx = new double [n][n];
		for (i=0;i<n;i++){
			for (j=0;j<n;j++){
				this.optMtx[i][j] = this.distance[match[i]][match[j]];
			}
		}
		
		
		///// test
		/*Random r = new Random();
		n = 5; // inc start, dec dest
		for (i=0;i<62;i++)
			if (i<n) match[i] = i;
		this.optN = n;
		
		this.optMtx = new double [n][n];
		for (i=0;i<n;i++){
			for (j=0;j<n;j++){
				this.optMtx[i][j] = r.nextDouble();
			}
		}*/
		//result ="asf";
		//if (true) return result;
		this.runGAMS();
		return result;
	}
	
	public String getVer()
	{
		return "13";
	}
	
	//////////////////////////
	public int getOptN(){
		return this.optN;
	}
	public double[][] getOptMtx(){
		return this.optMtx;
	}
	public ArrayList<Double> getFee(){
		ArrayList<Integer> candidlots = new ArrayList<Integer>();
		
		for (int i=1;i<this.optN;i++){
			//candidlots.add(this.findID(match[i]));
			candidlots.add(1);
		}

		return getParkFee(1,0,24,candidlots);
	}
	public ArrayList<Double> getWalk(){
		ArrayList<Double> walk = new ArrayList<Double>();

		for (int i=1;i<this.optN;i++){
			walk.add(300.0);
		}		
		return walk;
	}
	//////////////////////////
	MyParser mp;
	String result = "null";
	
	public int runGAMS(){
		String gamsCodePart1 = "";
		gamsCodePart1 = "$title Final Project Parking Lot\nfree variable Z;\noption optcr=0.0;\n";
		String gamsCodePart2 = "";
		gamsCodePart2 = "*** DATA END ***\n\nset Arc(N,N);\nArc(i,j) = yes;\n\nbinary variable Y(N);\nbinary variable X(N,N);\nnonnegative variable R(N,N);\nfree variable S(N);\nequations\nobj\nnLots\nstartpts\nbalance(N)\ncons1(N)\ncons2(N)\ncons3(N)\ncons4(N)\ncons5(N,N)\ncons6(N,N)\ncons7(N)\ncons8\n;\n\nobj..\nZ =e= w1*sum(P,F(P)*Y(P)) + w2*sum((i,j)$Arc(i,j),D(i,j)*R(i,j))+w3*sum(P,W(P)*Y(P));\n\nnLots..\nsum(P,Y(P)) =e= npts;\n\nstartpts..\nY(\'L0\') =e= 1;\n\nbalance(i)..\nsum(j$Arc(j,i),R(j,i))+S(i) =e= sum(j$Arc(i,j),R(i,j));\n\ncons1(i)..\nsum(j$Arc(i,j),X(i,j)) =l= 1;\n\ncons2(i)..\nsum(j$Arc(j,i),X(j,i)) =l= 1;\n\ncons3(i)..\nY(i) =g= (sum(j$Arc(i,j),X(i,j))+sum(j$Arc(j,i),X(j,i)))/2;\n\ncons4(i)..\nY(i) =l= (sum(j$Arc(i,j),X(i,j))+sum(j$Arc(j,i),X(j,i)));\n\ncons5(i,j)..\nR(i,j)/npts =l= X(i,j);\n\ncons6(i,j)..\nR(i,j) =g= X(i,j);\n\ncons7(i)$(ord(i) gt 2)..\nS(i) =e= -1*Y(i);\n\ncons8..\nS(\'L0\') =e= npts;\n\nmodel hw /\nobj\nnLots\nstartpts\nbalance\ncons1\ncons2\ncons3\ncons4\ncons5\ncons6\ncons7\ncons8\n/;\nsolve hw using mip minimizing Z ;\noption X:0:0:1 ;\noption Y:0:0:1 ;\noption R:0:0:1 ;\noption S:0:0:1 ;\ndisplay X.l,Y.l,R.l,S.l;\n";
		String dynamicData="";
		
		result = "" + getOptN() + "<br/>";
		for (int i=0;i<getOptN();i++){
			for (int j=0;j<getOptN();j++){
				result = result + this.optMtx[i][j] + " ";
			}
			result += "<br/>";
		}
		result += "<br/>";
		result +=  this.getWalk().size() + " " + this.getFee().size();
		dynamicData = DatatoGStr.toString(this.getOptN()-1, this.optMtx, this.getWalk(), this.getFee());
		//MySimApp myapp = new MySimApp();
		//System.out.println("Code Start ===\n"+gamsCodePart1+dynamicData+gamsCodePart2+"Code End====");
		
		result = "<plaintext>" + gamsCodePart1+dynamicData+gamsCodePart2 + "</plaintext>";
		/*result = myapp.submitJob(gamsCodePart1+dynamicData+gamsCodePart2);
		
		mp = new MyParser(result);
		mp.ParseResult(result);
		
		System.out.println("n arcs :"+Integer.toString(mp.narcs));
		System.out.println("path :"+Integer.toString(mp.arcs[0][0])+","+Integer.toString(mp.arcs[0][1]));
		System.out.println(" GetPath");
		int p[] = new int[this.getNarcs()];
		p = this.getPath();
		for( int i=0;i<this.getNarcs();i++){
			System.out.printf("p[%d] = %d\n",i,p[i]);
		}*/
		
		//result = "afjlsdfahlag";
		return 0;
	}
	public int getNarcs()
	{
		return this.mp.narcs;
	}
	public int[] getPath()
	{
		int[] p;
		p = new int[this.getNarcs()];
		int src =0;
		for (int i=0;i<this.getNarcs();i++){
			for(int j=0;j<this.getNarcs();j++)
			 if( mp.arcs[j][0]==src){
				 p[i] = mp.arcs[j][1];
				 src = p[i];
				 break;
			 }
		}
		return p;
	}
	
	public String[] getWays()
	{
		String[] ways= new String[this.getNarcs()];
		int[] p = this.getPath();
		for (int i=0;i<this.getNarcs();i++){
			ways[i] = (this.Lots[match[p[i]]]).getAddr();
		}
		return ways;
	}
	
	public static void main(String[] args) {
		/*calcFee cf = new calcFee();
		cf.loadData();
		System.out.println(cf.getN());
		String s = "975 University Ave, Madison, WI 53715, USA";
		cf.setNearD(s);
		//System.out.println(cf.Lots[31].getID());
		System.out.println(cf.findStID(s));
		//cf.setDist("START", "START", 10);
		cf.getOptimal();
		//ArrayList<Integer> candidlots = new ArrayList<Integer>();
		
		

		System.out.println(cf.getWays()[0]);*/
		System.out.println("sdf");
	}
}
